﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.IO;
using System.Drawing.Text;

namespace Walson.Form.FlightInstrument
{
        /// <summary>
        /// 圆形罗盘
        /// </summary>
        public partial class RoundCompass: UserControl
        {

            /// <summary>
            /// 前景色
            /// </summary>
            public override Color ForeColor
            {
                get
                {
                    return base.ForeColor;
                }
                set
                {
                    base.ForeColor = value;
                    _Pen = new Pen(value, 2);
                    LoadResource();
                    DrawElement();
                    this.Invalidate();
                }

            }

            /// <summary>
            /// 背景色
            /// </summary>
            public override Color BackColor
            {
                get
                {
                    return base.BackColor;
                }
                set
                {
                    base.BackColor = value;
                    DrawElement();
                    this.Invalidate();
                }
            }

            private int _Heading;
            /// <summary>
            /// 当前的航向
            /// </summary>
            public int Heading
            {
                get
                {
                    return _Heading;
                }
                set
                {
                    while (_Heading > 360)
                        _Heading -= 360;
                    while (_Heading < 0)
                        _Heading += 360;
                    _Heading = value;
                    this.Invalidate();
                }
            }

            private bool _CenterRotate;
            /// <summary>
            /// 是否中心旋转
            /// </summary>
            public bool CenterRotate
            {
                get
                {
                    return _CenterRotate;
                }
                set
                {
                    _CenterRotate = value;
                    this.Invalidate();
                }
            }

            private int _ShortMarkerLength = 5;
            /// <summary>
            /// 短刻度的长度
            /// </summary>
            public int ShortMarkerLength
            {
                get
                {
                    return _ShortMarkerLength;
                }
                set
                {
                    _ShortMarkerLength = value;
                    DrawElement();
                    this.Invalidate();
                }
            }

            private int _LongMarkerLength = 10;
            /// <summary>
            /// 长刻度的长度
            /// </summary>
            public int LongMarkerLength
            {
                get
                {
                    return _LongMarkerLength;
                }
                set
                {
                    _LongMarkerLength = value;
                    DrawElement();
                    this.Invalidate();
                }
            }

            /// <summary>
            /// 字体
            /// </summary>
            public Font Font
            {
                get
                {
                    return base.Font;
                }
                set
                {
                    base.Font = value;
                    DrawElement();
                    this.Invalidate();
                }
            }

            private Size _PlaneSize;
            private Size _OriginalSize;
            private Bitmap _Plane;
            private Bitmap _bmp;
            private Pen _Pen;
            private float _PlaneScaleFactor = 1.0f;

            private void LoadResource()
            {
                Assembly myAssembly = Assembly.GetExecutingAssembly();
                Stream myStream = myAssembly.GetManifestResourceStream("Walson.Resources.Plane.png");
                Bitmap bmp = new Bitmap(myStream);
                Bitmap bmp2 = new Bitmap((int)(bmp.Width * _PlaneScaleFactor), (int)(bmp.Height * _PlaneScaleFactor));


                for (int i = 0; i < bmp.Width; i++)
                    for (int j = 0; j < bmp.Height; j++)
                    {
                        if (bmp.GetPixel(i, j).A != 0)
                            bmp.SetPixel(i, j, base.ForeColor);
                    }

                using (Graphics g = Graphics.FromImage(bmp2))
                {
                    g.ScaleTransform(_PlaneScaleFactor, _PlaneScaleFactor);
                    g.DrawImage(bmp, 0, 0);
                    g.ResetTransform();

                }

                _Plane = bmp2;
                _PlaneSize = bmp2.Size;
                _OriginalSize = bmp.Size;
            }



            private void DrawElement()
            {
                int max = Math.Max(this.Width, this.Height);
                int min = Math.Min(this.Width, this.Height);
                int r = -min / 2;
                Bitmap bmp = new Bitmap(min, min);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.TranslateTransform(min / 2f, min / 2f);
                    g.Clear(this.BackColor);

                    PointF[] line = new PointF[2];
                    for (int i = 0; i < 60; i++)
                    {
                        line[0] = new PointF(0, r + 10);

                        if (i % 5 == 0)
                        {
                            line[1] = new PointF(0, r + _LongMarkerLength+10);
                            int angle = i * 6;
                            SizeF size = g.MeasureString(angle.ToString(), this.Font);
                            g.DrawString(angle.ToString(), this.Font, new SolidBrush(base.ForeColor), -size.Width / 2, r + _LongMarkerLength + 15);

                        }
                        else
                        {
                            line[1] = new PointF(0, r + _ShortMarkerLength+10);
                        }
                        g.DrawLine(_Pen, line[0], line[1]);

                        g.RotateTransform(6);
                    }
                }
                _bmp = bmp;
            }

            /// <summary>
            /// 圆形罗盘
            /// </summary>
            public RoundCompass()
            {
                InitializeComponent();

                _Pen = new Pen(base.ForeColor, 2);
                this.DoubleBuffered = true;
                _PlaneScaleFactor = 1;

                this.DoubleBuffered = true;

                LoadResource();

                this.SizeChanged += new EventHandler(FlightCompass_SizeChanged);

                this.Size = new Size(90, 90);
                this.ForeColor = Color.White;
                this.BackColor = Color.FromArgb(16, 16, 49);

                DrawElement();
            }

            private void FlightCompass_SizeChanged(object sender, EventArgs e)
            {
                int min = Math.Min(this.Width, this.Height);
                int r = -min / 2;
                DrawElement();
                try
                {
                    _PlaneScaleFactor = (float)((-r - 30.0) / _OriginalSize.Width);
                }
                catch (System.Exception)
                {
                    _PlaneScaleFactor = 1f;
                }

                if (_PlaneScaleFactor <= 0)
                    _PlaneScaleFactor = 1f;

                LoadResource();
                this.Invalidate();
            }

            /// <summary>
            /// 圆形罗盘
            /// </summary>
            public RoundCompass(IContainer container)
            {
                container.Add(this);

                InitializeComponent();

                _Pen = new Pen(base.ForeColor, 2);
                this.DoubleBuffered = true;
                _PlaneScaleFactor = 1;

                this.DoubleBuffered = true;

                LoadResource();

                this.SizeChanged += new EventHandler(FlightCompass_SizeChanged);

                this.Size = new Size(90, 90);
                this.ForeColor = Color.White;
                this.BackColor = Color.FromArgb(16, 16, 49);

                DrawElement();
            }

            /// <summary>
            /// 绘制控件
            /// </summary>
            /// <param name="e">参数</param>
            protected override void OnPaint(PaintEventArgs e)
            {
                if (_bmp == null)
                    return;

                int min = Math.Min(this.Width, this.Height);
                int max = Math.Max(this.Width, this.Height);
                int r = -min / 2;
                //int r = 0;

                using (Bitmap bmp = new Bitmap(this.Width, this.Height))
                {
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                        g.TextRenderingHint = TextRenderingHint.AntiAlias;

                        g.Clear(BackColor);

                        SizeF fontSize = g.MeasureString("5", this.Font);

                        if (_CenterRotate)
                        {                           

                            g.TranslateTransform(this.Width / 2f, this.Height / 2f);

                            g.DrawImage(_bmp, -_bmp.Width/2f, -_bmp.Height/2f);

                            g.RotateTransform(_Heading);                        // 绘制三角形
                            PointF[] triangle = new PointF[4];
                            triangle[0] = new PointF(0, fontSize.Height+20 + r+_LongMarkerLength);
                            triangle[1] = new PointF(-7, fontSize.Height+30 + r + _LongMarkerLength);
                            triangle[2] = new PointF(7, fontSize.Height+30 + r + _LongMarkerLength);
                            triangle[3] = new PointF(0, fontSize.Height+20 + r + _LongMarkerLength);
                            //g.DrawLines(Pens.White, triangle);
                            g.FillPolygon(new SolidBrush(base.ForeColor), triangle);

                            g.DrawImage(_Plane, -_Plane.Width / 2f, -_Plane.Height / 2f);
                        }
                        else
                        {
                            g.TranslateTransform(this.Width / 2f, this.Height / 2f);

                            g.RotateTransform(-_Heading);

                            //g.DrawImage(_bmp, -_bmp.Width / 2, -_bmp.Height / 2);
                            PointF[] line = new PointF[2];
                            for (int i = 0; i < 60; i++)
                            {
                                line[0] = new PointF(0, r + 10);

                                if (i % 5 == 0)
                                {
                                    line[1] = new PointF(0, r + _LongMarkerLength+10);
                                    int angle = i * 6;
                                    SizeF size = g.MeasureString(angle.ToString(), this.Font);
                                    g.DrawString(angle.ToString(), this.Font, new SolidBrush(base.ForeColor), -size.Width / 2, r + _LongMarkerLength+15 );

                                }
                                else
                                {
                                    line[1] = new PointF(0, r + _ShortMarkerLength+10);
                                }
                                g.DrawLine(_Pen, line[0], line[1]);

                                g.RotateTransform(6);
                            }




                            g.ResetTransform();
                            g.TranslateTransform(this.Width / 2f, this.Height / 2f);

                            // 绘制三角形
                            PointF[] triangle = new PointF[4];
                            triangle[0] = new PointF(0, fontSize.Height + 20 + r + _LongMarkerLength);
                            triangle[1] = new PointF(-7, fontSize.Height + 30 + r + _LongMarkerLength);
                            triangle[2] = new PointF(7, fontSize.Height + 30 + r + _LongMarkerLength);
                            triangle[3] = new PointF(0, fontSize.Height + 20 + r + _LongMarkerLength);
                            //g.DrawLines(Pens.White, triangle);
                            g.FillPolygon(new SolidBrush(base.ForeColor), triangle);

                            g.DrawImage(_Plane, -_Plane.Width / 2f, -_Plane.Height / 2f);
                        }

                        g.ResetTransform();
                    }
                    e.Graphics.DrawImage(bmp, 0, 0);
                }

                // 绘制圆角控件
                Rectangle rect = new Rectangle(0, 0, base.Width, base.Height);
                int radius = 50;
                System.Drawing.Drawing2D.GraphicsPath roundRect = new System.Drawing.Drawing2D.GraphicsPath();
                //顶端 
                roundRect.AddLine(rect.Left + radius - 1, rect.Top - 1, rect.Right - radius, rect.Top - 1);
                //右上角 
                roundRect.AddArc(rect.Right - radius, rect.Top - 1, radius, radius, 270, 90);
                //右边 
                roundRect.AddLine(rect.Right, rect.Top + radius, rect.Right, rect.Bottom - radius);
                //右下角
                roundRect.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90);
                //底边 
                roundRect.AddLine(rect.Right - radius, rect.Bottom, rect.Left + radius, rect.Bottom);
                //左下角 
                roundRect.AddArc(rect.Left - 1, rect.Bottom - radius, radius, radius, 90, 90);
                //左边 
                roundRect.AddLine(rect.Left - 1, rect.Top + radius, rect.Left - 1, rect.Bottom - radius);
                //左上角 
                roundRect.AddArc(rect.Left - 1, rect.Top - 1, radius, radius, 180, 90);
                this.Region = new Region(roundRect);

                base.OnPaint(e);
            }
        }

   
}
